import { fireEvent, render, screen } from '@app-nextmesh/utils';
import '@testing-library/jest-dom';

import NumberInput from './NumberInput';

const setup = async (
  type: 'double' | 'int',
  name: string,
  value: number,
  onInputChange: (value: number) => void,
) => {
  const utils = render(
    <NumberInput
      type={type}
      value={value}
      onChange={onInputChange}
    />,
  );
  const input: HTMLInputElement = await screen.findByDisplayValue('' + value);
  return {
    ...utils,
    input,
  };
};

describe('NumberInput', () => {
  test('double render', async () => {
    const initValue = 12.0;
    const { input } = await setup('double', 'name', initValue, () => {});
    expect(input.value).toBe(initValue.toString());
  });
  test('double change', async () => {
    const initValue = 12.0;
    const { input } = await setup('double', 'name', initValue, () => {});
    fireEvent.change(input, { target: { value: 1 } });
    expect(input.value).toBe('1');
  });
  test('double blur', async () => {
    const initValue = 12.0;
    const { input } = await setup('double', 'name', initValue, () => {});
    fireEvent.change(input, { target: { value: 'a' } }); // 无法转成数字的，保持原值
    fireEvent.blur(input);
    expect(input.value).toBe(initValue.toString());
  });
  test('double blur 2', async () => {
    const initValue = 12.0;
    const { input } = await setup('double', 'name', initValue, () => {});
    fireEvent.change(input, { target: { value: '.2' } });
    fireEvent.blur(input);
    expect(input.value).toBe('0.2');
  });
  test('int render', async () => {
    const initValue = 12;
    const { input } = await setup('int', 'name', initValue, () => {});
    expect(input.value).toBe(initValue.toString());
  });
  test('int change', async () => {
    const initValue = 12;
    const { input } = await setup('int', 'name', initValue, () => {});
    fireEvent.change(input, { target: { value: 1 } });
    expect(input.value).toBe('1');
  });
  test('int blur', async () => {
    const initValue = 12;
    const { input } = await setup('int', 'name', initValue, () => {});
    fireEvent.change(input, { target: { value: 'a' } });
    fireEvent.blur(input);
    expect(input.value).toBe(initValue.toString()); // 无法转成数字的，保持原值
  });
  test('int blur 2', async () => {
    const initValue = 12;
    const { input } = await setup('int', 'name', initValue, () => {});
    fireEvent.change(input, { target: { value: '2.' } });
    fireEvent.blur(input);
    // expect(input.value).toBe('2') // 在浏览器中console.log 会打印 2，在这里却还原成 initValue2 了
    expect(input.value).toBe(initValue.toString());
  });
  test('rerender', async () => {
    let initValue = 24;
    const { input, rerender } = await setup('int', 'name', initValue, () => {});
    expect(input.value).toBe(initValue.toString());
    initValue = 12.3;
    rerender(
      <NumberInput
        type='double'
        value={initValue}
        onChange={() => {}}
      />,
    );
    expect(input.value).toBe(initValue.toString());
  });
});
